package com.fingard.dsp.bank.directbank.boqh01;

import com.fingard.FGBiz;
import com.fingard.constant.Format;
import com.fingard.db.JDBCHelper;
import com.fingard.dsp.bank.directbank.bankInterface.ISinglePay;
import com.fingard.dsp.bank.reqrespobj.single.*;
import com.fingard.dsp.bank.reqrespobj.single.detail.RetAtsSglDetail;
import com.fingard.xml.XElement;
import com.fingard.xml.XmlTextReader;
import com.fingard.xml.XmlTextWriter;

import java.sql.Connection;
import java.util.Date;
import java.util.Map;

/**
 * 测试代码，签名等配置没有测试环境，等有了测试环境再改动
 * @ClassName BOQH01SinglePay
 * @Author Zhengzy
 * @Date 2020/3/12 13:57
 * @Version 1.0
 **/
public class BOQH01SinglePay extends BOQH01Base implements ISinglePay {
    // 用20位的企业流水号查询支付状态
    private static final String INSERTRECEIPT = "INSERT INTO REQSEQIDMAPPING(URID,BANKCODE,REQSEQID,BANKREQSEQID) values (?,?,?,?);";
    private static final String SELECTRECEIPT = "SELECT REQSEQID FROM REQSEQIDMAPPING WHERE BANKREQSEQID=? and BANKCODE=?;";

    @Override
    public RetAtsSingle d_1908_SglPay(ReqSingle p_req1908) throws Exception {
        RetAtsSingle retAts = new RetAtsSingle(p_req1908.reqHeader);
        RetAtsSglDetail detail = new RetAtsSglDetail();
        Connection conn = FGBiz.getLocalDbConn();
        try {
            if (!"1".equals(p_req1908.singleDetail.payCur)) {
                detail.reqSeqID = "000" + p_req1908.reqHeader.transSeqID;
                detail.respCode = "0";
                detail.respInfo = "青海银行不支持除人民币外的其他币种";
                detail.transState = "91";
                retAts.writeRetDetail(detail);
                return retAts;
            }

            // 组装报文 同行、跨行公共报文部分
            String cstNo = getBankConfig().getValueAsString("CSTNO");
            XmlTextWriter xmlTextWriter = new XmlTextWriter();
            XElement bankData = new XElement("BankData", "");
            XElement opReq = new XElement("opReq", "");
            opReq.addChild(new XElement("cstNo", cstNo));// 企业编号
            Date date = new Date();
            String serialNo = "000" + Format.DateTime17SSSFormat.format(date);
            String reqTime = Format.DateTime14Format.format(date);
            opReq.addChild(new XElement("serialNo", serialNo));// 企业流水号固定为20位，不允许重复
            opReq.addChild(new XElement("reqTime", reqTime));// 客户端请求时间yyyymmddhhmmss
            XElement ReqParam = new XElement("ReqParam", "");
            ReqParam.addChild(new XElement("payAccount", p_req1908.singleDetail.payAct));// 付款户账号
            ReqParam.addChild(new XElement("recAccount", p_req1908.singleDetail.recAct));// 收款户账号
            ReqParam.addChild(new XElement("recAccountName", p_req1908.singleDetail.recName));// 收款户名称
            ReqParam.addChild(new XElement("payAmount", p_req1908.singleDetail.payAmount));// 交易金额
            ReqParam.addChild(new XElement("currencyType", "10"));// 币种  10：人民币

            // 需要签名的内容
            String strBeforeSign = cstNo + "|" + p_req1908.singleDetail.payAct + "|" + p_req1908.singleDetail.payAmount + "|" + serialNo + "|" + reqTime + "|" + p_req1908.singleDetail.recAct;
            // 返回签名后的数据
            String strAfterSign = SendTranInfoToBankForSign(strBeforeSign);
            if (strAfterSign == "") {
                detail.respCode = "-1";
                detail.respInfo = "签名失败";
                retAts.writeRetDetail(detail);
                return retAts;
            }
            String[] invildArr = IsResultInvlid(strAfterSign);

            if ("true".equals(invildArr[2])) {
                StringBuilder tmpSbMsg = new StringBuilder();
                XmlTextReader tmpBkReader = loadBankRespXmlReader(invildArr[3], tmpSbMsg);
                if (tmpBkReader != null) {
                    String successFlag = tmpBkReader.readedXElement.getSingleText("result");
                    if ("0".equals(successFlag)) {
                        String sign = tmpBkReader.readedXElement.getSingleText("sign");
                        ReqParam.addChild(new XElement("ReqReserved1", sign));
                    } else {
                        detail.respCode = "-999";
                        detail.respInfo = "银行签名失败";
                        retAts.writeRetDetail(detail);
                        return retAts;
                    }
                }
            } else {
                // 到银行签名报错
                detail.respCode = invildArr[0];
                detail.respInfo = invildArr[1];
                retAts.writeRetDetail(detail);
                return retAts;
            }
            // 银行返回
            String[] bankResult = {"", ""};
            // 人民币同行、跨行
            if ("1".equals(p_req1908.singleDetail.sameBnk)) {
                // 单笔行内转账 190801
                ReqParam.addChild(new XElement("payUse", ""));// 用途
                opReq.addChild(ReqParam);
                bankData.addChild(opReq);
                nodeAnalysis(p_req1908.singleDetail.srcXElement, ReqParam, getCharset());
                xmlTextWriter.writeXElement(bankData);
                xmlTextWriter.writeEndDocument();
                bankResult = sendToBank(xmlTextWriter.toXmlString(), "CBE003");
            } else {
                // 单笔跨行转账交易 190802
                ReqParam.addChild(new XElement("recAccountOpenBank", p_req1908.singleDetail.cnapsName));// 收款开户行
                ReqParam.addChild(new XElement("unionBankNo", p_req1908.singleDetail.cnapsCode));// 行联号
                ReqParam.addChild(new XElement("rmtType", p_req1908.singleDetail.paySpd));// 加急方式0：普通，1：加急
                ReqParam.addChild(new XElement("payUse", ""));// 用途
                opReq.addChild(ReqParam);
                bankData.addChild(opReq);
                nodeAnalysis(p_req1908.singleDetail.srcXElement, ReqParam, getCharset());
                xmlTextWriter.writeXElement(bankData);
                xmlTextWriter.writeEndDocument();
                bankResult = sendToBank(xmlTextWriter.toXmlString(), "CBE004");
            }
            // 测试数据
           /* bankResult[0] = "";
            bankResult[1] = "<BankData>\n" +
                    "   <opReq>\n" +
                    "     <opResult>\n" +
                    "        <orderState>2</orderState>\n" +
                    "     </opResult>\n" +
                    "   </opReq>\n" +
                    "</BankData>";*/
            if (bankResult[0].length() == 0) {
                // 解析签名
                String[] invildArr2 = IsResultInvlid(bankResult[1]);
                if ("true".equals(invildArr2[2])) {
                    StringBuilder SbMsg = new StringBuilder();
                    XmlTextReader reader = loadBankRespXmlReader(invildArr2[3], SbMsg);
                    if (reader != null) {
                        // 存入企业流水号，用于查询
                        JDBCHelper.update(conn, INSERTRECEIPT, new Object[]{p_req1908.reqHeader.reqSeqID, p_req1908.reqHeader.bankCode, p_req1908.reqHeader.reqSeqID, p_req1908.reqHeader.reqSeqID});
                        detail.respCode = "0";
                        detail.reqSeqID = p_req1908.reqHeader.reqSeqID;
                        detail.transState = reader.getSimpleTextNotNull("orderState");
                        detail.payInfoCode = reader.getSimpleTextNotNull("orderState");
                        retAts.writeRetDetail(detail);
                    }
                } else {
                    retAts.writeRespCode(invildArr2[0]);
                    retAts.writeRespInfo(invildArr2[1]);
                }
            } else {
                retAts.writeRespCode("-1");
                retAts.writeRespInfo(bankResult[1]);
            }
        } catch (Exception e) {
            retAts.writeRespCode("-1");
            retAts.writeRespInfo(e.getMessage());
        } finally {
            conn.close();
        }
        retAts.writeEnd();
        return retAts;
    }

    @Override
    public RetAtsSingle d_1944_QrySglPay(ReqQrySingle p_req1944) throws Exception {
        // 返回给ATS的对象
        RetAtsSingle retAts = new RetAtsSingle(p_req1944.reqHeader);
        RetAtsSglDetail detail = new RetAtsSglDetail();
        Connection conn = FGBiz.getLocalDbConn();
        try {
            String cstNo = getBankConfig().getValueAsString("CSTNO");
            XmlTextWriter xmlTextWriter = new XmlTextWriter();
            XElement bankData = new XElement("BankData", "");
            XElement opReq = new XElement("opReq", "");
            opReq.addChild(new XElement("cstNo", cstNo));// 企业编号
            Date date = new Date();
            String serialNo = "000" + Format.DateTime17SSSFormat.format(date);
            String reqTime = Format.DateTime14Format.format(date);
            opReq.addChild(new XElement("serialNo", serialNo));// 企业流水号固定为20位，不允许重复
            opReq.addChild(new XElement("reqTime", reqTime));// 客户端请求时间yyyymmddhhmmss
            XElement ReqParam = new XElement("ReqParam", "");
            Map<String, Object> map = JDBCHelper.execQuerySingle(conn, SELECTRECEIPT, new Object[]{p_req1944.askNumber, p_req1944.reqHeader.bankCode});
            if (map.size() == 0) {
                detail.respCode = "-1";
                detail.respInfo = "没有这条请求映射的流水号！";
                retAts.writeRetDetail(detail);
                return retAts;
            }
            ReqParam.addChild(new XElement("orderFlowNo", map.get("REQSEQID").toString()));
            opReq.addChild(ReqParam);
            bankData.addChild(opReq);
            xmlTextWriter.writeXElement(bankData);
            xmlTextWriter.writeEndDocument();

            // 发送银行
            String[] bankResult = sendToBank(xmlTextWriter.toXmlString(), "CBE005");
            // 测试
            /*String[] bankResult = {"", "<BankData>\n" +
                    "   <opReq>\n" +
                    "      <opResult>\n" +
                    "         <Proc_stat>3</Proc_stat>\n" +
                    "         <orderFlowDescript>2</orderFlowDescript>\n" +
                    "      </opResult>\n" +
                    "   </opReq>\n" +
                    "</BankData> "};*/
            if (bankResult[0].length() == 0) {
                // 解析签名
                String[] invildArr = IsResultInvlid(bankResult[1]);
                if ("true".equals(invildArr[2])) {
                    StringBuilder tmpSbMsg = new StringBuilder();
                    XmlTextReader tmpBkReader = loadBankRespXmlReader(invildArr[3], tmpSbMsg);
                    if (tmpBkReader != null) {
                        detail.reqSeqID = p_req1944.reqHeader.reqSeqID;
                        detail.transState = tmpBkReader.getSimpleTextNotNull("Proc_stat");
                        detail.payInfoCode = tmpBkReader.getSimpleTextNotNull("Proc_stat");
                        detail.respInfo = tmpBkReader.getSimpleTextNotNull("orderFlowDescript");
                        retAts.writeRetDetail(detail);
                    }
                } else {
                    // 签名错误
                    retAts.writeRespCode(invildArr[0]);
                    retAts.writeRespInfo(invildArr[1]);
                }
            } else {
                // 指令出错
                retAts.writeRespCode("-1");
                retAts.writeRespInfo(bankResult[1]);
            }
        } catch (Exception e) {
            retAts.writeRespCode("-1");
            retAts.writeRespInfo(e.getMessage());
        } finally {
            conn.close();
        }
        retAts.writeEnd();
        return retAts;
    }

    @Override
    public RetAtsSingleBat d_1908BAT_SglBatPay(ReqSingleBat p_req1908BAT) throws Exception {
        return null;
    }

    @Override
    public RetAtsSingleBat d_1944BAT_QrySglBatPay(ReqQrySingleBat p_req1944BAT) throws Exception {
        return null;
    }
}
